package com.spira.imp;

import java.io.IOException;

import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.DefaultHttpClient;

import com.spira.SpiraRunnerConfig;
import com.spira.SpiraSoapConfig;
import com.spira.SpiraTestRecorder;
import com.spira.SpiraTestRun;
import com.spira.SpiraUser;
import com.spira.XmlDate;

public class SpiraTestRecorderImp implements SpiraTestRecorder {

	private final SpiraRunnerConfig runnerConfiguration;
	
	private final SpiraSoapConfig soapConfiguration;
	
	public SpiraTestRecorderImp(SpiraRunnerConfig runnerConfig, SpiraSoapConfig soapConfig){
		
		this.runnerConfiguration = runnerConfig;
		
		this.soapConfiguration = soapConfig;
	}
	
	public void sendTestRun(SpiraUser user, SpiraTestRun testRun) {
		
		if(user != null && testRun != null){
			
			try {
				sendSpiraRunRequest(user, testRun);
			}
		    catch (IOException e) {
		      
		    	throw new IllegalStateException(String.format("Coudln't send spira test run '%s'", testRun.getTestId()), e); 
		    }
		}
		else
			throw new NullPointerException("User and testRun cannot be null");
	}
	
	private void sendSpiraRunRequest(SpiraUser user, SpiraTestRun testRun) throws IOException{
		
		DefaultHttpClient client = new DefaultHttpClient();
	     
        HttpPost httpget = new HttpPost(runnerConfiguration.getHost() + soapConfiguration.getWsdlUrl());

        httpget.addHeader("SOAPAction", "\"" + soapConfiguration.getApiVersionUrl() + soapConfiguration.getRecordTestSoapAction() + "\"");

        String requestBody = generateSoapRequestBody(user, testRun);
        
        StringEntity strent= new StringEntity(requestBody);
        strent.setContentType("text/xml; charset=utf-8");
        httpget.setEntity(strent);

        ResponseHandler<String> response = new BasicResponseHandler();
        client.execute(httpget, response);
	}
	
	private String generateSoapRequestBody(SpiraUser user, SpiraTestRun testRun){
		
		String startDate = XmlDate.getActualDate();
		String username = user.getUserName();
		String password = user.getUserPassword();
		int projectId = runnerConfiguration.getProjectId();
		int userId = user.getUserId();
		int testId = testRun.getTestId();
		int releaseId = runnerConfiguration.getReleaseId();
		int statusCode = testRun.getStatus().getCode();
		String runnerName = runnerConfiguration.getRunnerName();
		String testName = testRun.getInfo().getName();
		String testMessage = testRun.getInfo().getMessage();
		String stackTrace = testRun.getInfo().getStackTrace();
		String endDate = XmlDate.getActualDate();
		
		
		StringBuffer body = new StringBuffer();
		body.append("<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:v3=\"" + soapConfiguration.getApiVersionUrl() + "\">");
		body.append("<soapenv:Header/>");
		body.append("<soapenv:Body>");
		body.append("<v3:TestRun_RecordAutomated2>");
		body.append("<v3:userName>" + username + "</v3:userName>");
		body.append("<v3:password>" + password + "</v3:password>");
		body.append("<v3:projectId>" + projectId + "</v3:projectId>");
		body.append("<v3:testerUserId>" + userId + "</v3:testerUserId>");
		body.append("<v3:testCaseId>" + testId + "</v3:testCaseId>");
		body.append("<v3:releaseId>" + releaseId + "</v3:releaseId>");
		body.append("<v3:startDate>" + startDate + "</v3:startDate>");
		body.append("<v3:endDate>" + endDate + "</v3:endDate>");
		body.append("<v3:executionStatusId>" + statusCode + "</v3:executionStatusId>");
		body.append("<v3:runnerName>" + runnerName + "</v3:runnerName>");
		body.append("<v3:runnerTestName>" + testName + "</v3:runnerTestName>");
		body.append("<v3:runnerMessage>" + testMessage + "</v3:runnerMessage>");
		body.append("<v3:runnerStackTrace>" + stackTrace + "</v3:runnerStackTrace>");
		body.append("</v3:TestRun_RecordAutomated2>");
		body.append("</soapenv:Body>");
		body.append("</soapenv:Envelope>");
		
		return body.toString();
	}
}
